﻿using System;
using System.Runtime.CompilerServices;
using C4Net.Framework.Core.IoC;

namespace C4Net.Framework.Core.Log
{
    /// <summary>
    /// Default logger of the application, resolves the ILoggable instance using IoC the first time that is accessed.
    /// </summary>
    public static class DefaultLogger
    {
        #region - Fields -

        /// <summary>
        /// Static field for the ILoggable instance.
        /// </summary>
        private static ILoggable logger = null;

        /// <summary>
        /// Indicates if the logger has been assigned, even if is null, to avoid trying to reload it.
        /// </summary>
        private static bool loggerAssigned = false;

        #endregion

        #region - Properties -

        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <value>
        /// The logger.
        /// </value>
        public static ILoggable Logger
        {
            get
            {
                if (!loggerAssigned)
                {
                    logger = IoCDefault.Get<ILoggable>();
                    loggerAssigned = true;
                }
                return logger;
            }
        }

        #endregion

        #region - Methods -

        /// <summary>
        /// Writes a message into a given logger.
        /// </summary>
        /// <param name="loggerName">Name of the logger.</param>
        /// <param name="severity">The severity of the issue.</param>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void WriteLog(string loggerName, LogSeverity severity, string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.WriteLog(loggerName, severity, message, className, memberName);
            }
        }

        /// <summary>
        /// Writes an exception into a given logger.
        /// </summary>
        /// <param name="loggerName">Name of the logger.</param>
        /// <param name="severity">The severity of the issue.</param>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void WriteLog(string loggerName, LogSeverity severity, Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.WriteLog(loggerName, severity, ex, className, memberName);
            }
        }

        /// <summary>
        /// Writes a message into the default logger.
        /// </summary>
        /// <param name="severity">The severity of the issue.</param>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void WriteLog(LogSeverity severity, string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.WriteLog(severity, message, className, memberName);
            }
        }

        /// <summary>
        /// Writes an exception to the default logger.
        /// </summary>
        /// <param name="severity">The severity of the issue.</param>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void WriteLog(LogSeverity severity, Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.WriteLog(severity, ex, className, memberName);
            }
        }

        /// <summary>
        /// Logs a debug message into the default logger.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogDebug(string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogDebug(message, className, memberName);
            }
        }

        /// <summary>
        /// Logs a debug exception into the default logger.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogDebug(Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogDebug(ex, className, memberName);
            }
        }

        /// <summary>
        /// Logs an information message into the default logger.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogInfo(string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogInfo(message, className, memberName);
            }
        }

        /// <summary>
        /// Logs an information exception into the default logger.
        /// </summary>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogInfo(Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogInfo(ex, className, memberName);
            }
        }

        /// <summary>
        /// Logs a warning message into the default logger.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogWarning(string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogWarning(message, className, memberName);
            }
        }

        /// <summary>
        /// Logs a warning exception into the default logger.
        /// </summary>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogWarning(Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogWarning(ex, className, memberName);
            }
        }

        /// <summary>
        /// Logs an error message into the default logger.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogError(string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogError(message, className, memberName);
            }
        }

        /// <summary>
        /// Logs an error exception into the default logger.
        /// </summary>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogError(Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogError(ex, className, memberName);
            }
        }

        /// <summary>
        /// Logs a fatal message into the default logger.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogFatal(string message, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogFatal(message, className, memberName);
            }
        }

        /// <summary>
        /// Logs a fatal exception into the default logger.
        /// </summary>
        /// <param name="ex">The exception.</param>
        /// <param name="className">Name of the class.</param>
        /// <param name="memberName">Name of the member.</param>
        public static void LogFatal(Exception ex, string className = "", [CallerMemberName] string memberName = "")
        {
            if (Logger != null)
            {
                Logger.LogFatal(ex, className, memberName);
            }
        }

        #endregion
    }
}
